import { useMemo } from 'react'
import { DefaultSizeStyle, onDragFromToolbarToCreateShape, TLUiOverrides, VecModel } from 'tldraw'
import { trackEvent } from '../../../utils/analytics'

export function useExtraDragIconOverrides() {
	const overrides = useMemo<TLUiOverrides>(() => {
		return {
			tools(editor, tools) {
				tools.select.onDragStart = function (source, info) {
					onDragFromToolbarToCreateShape(editor, info, {
						createShape: (id) => {
							const sizeStyle = editor.getStyleForNextShape(DefaultSizeStyle)
							return editor.createShape({
								id,
								type: 'draw',
								props: {
									segments: [
										{
											type: 'free',
											points: scalePoints(POINTER_POINTS, SCALES[sizeStyle]),
										},
									],
									isClosed: true,
								},
							})
						},
					})

					trackEvent('drag-tool', { source, id: 'select' })
				}

				tools.hand.onDragStart = function (source, info) {
					onDragFromToolbarToCreateShape(editor, info, {
						createShape: (id) => {
							const sizeStyle = editor.getStyleForNextShape(DefaultSizeStyle)
							return editor.createShape({
								id,
								type: 'draw',
								props: {
									segments: [
										{
											type: 'free',
											points: scalePoints(HAND_POINTS, SCALES[sizeStyle]),
										},
									],
									isClosed: true,
								},
							})
						},
					})

					trackEvent('drag-tool', { source, id: 'hand' })
				}

				tools.draw.onDragStart = function (source, info) {
					onDragFromToolbarToCreateShape(editor, info, {
						createShape: (id) => {
							const sizeStyle = editor.getStyleForNextShape(DefaultSizeStyle)
							return editor.createShape({
								id,
								type: 'draw',
								props: {
									segments: [
										{
											type: 'free',
											points: scalePoints(DRAW_POINTS, SCALES[sizeStyle]),
										},
									],
									isClosed: true,
								},
							})
						},
					})
					trackEvent('drag-tool', { source, id: 'draw' })
				}

				return tools
			},
		}
	}, [])

	return overrides
}

const HAND_POINTS: VecModel[] = []

const RAW_HAND_POINTS = [
	43.63, 80, 43.74, 80, 44.3, 80, 45.21, 80, 46.42, 80, 48.07, 79.99, 50.25, 79.61, 52.6, 78.71,
	54.74, 77.62, 56.78, 76.27, 58.47, 74.64, 59.93, 72.91, 61.49, 70.9, 63.23, 68.09, 64.83, 64.78,
	66, 60.86, 67.03, 56.15, 68.09, 51.16, 69.08, 46.08, 69.81, 40.84, 70.04, 35.63, 70.04, 31.11,
	70.04, 27.7, 70.04, 25.2, 70.04, 23.17, 69.85, 21.66, 69.3, 20.46, 68.65, 19.51, 68.15, 19.02,
	67.77, 18.79, 67.49, 18.72, 67.19, 18.72, 66.68, 18.73, 65.69, 19.09, 64.22, 20.19, 62.6, 21.76,
	61.41, 23.4, 60.61, 24.85, 60, 26.59, 59.53, 28.56, 59.15, 30.24, 59, 31.65, 59, 33.07, 59, 34.62,
	59, 36.57, 58.9, 38.91, 58.66, 41.99, 58.37, 45.15, 58.1, 47.81, 57.86, 49.91, 57.67, 51.06,
	57.58, 51.56, 57.57, 51.85, 57.57, 51.88, 57.57, 51.52, 57.57, 50.64, 57.57, 48.58, 57.57, 45.31,
	57.57, 41.03, 57.57, 35.92, 57.57, 30.56, 57.57, 25.55, 57.33, 20.51, 56.83, 16.25, 56.18, 12.95,
	55.29, 9.83, 54.3, 7.37, 53.48, 5.56, 52.85, 4.41, 52.42, 3.78, 52.14, 3.55, 51.92, 3.41, 51.71,
	3.25, 51.48, 3.22, 51.27, 3.22, 50.92, 3.22, 50.32, 3.22, 49.48, 3.75, 48.57, 4.91, 47.91, 6.22,
	47.38, 7.9, 46.91, 10.11, 46.41, 12.68, 45.92, 15.96, 45.73, 19.72, 45.73, 23.66, 45.73, 28.01,
	45.54, 32.76, 45.29, 36.83, 45.14, 40.24, 45.01, 43, 44.9, 44.54, 44.8, 45.24, 44.73, 45.55,
	44.73, 45.48, 44.73, 44.47, 44.77, 42.21, 44.95, 38.61, 45.09, 33.96, 45.09, 29.27, 45.09, 24.91,
	45.09, 20.8, 45.09, 17.05, 45.09, 13.55, 45.03, 10.61, 44.75, 8.61, 44.36, 7.42, 44.11, 6.75,
	43.97, 6.47, 43.73, 6.08, 43.38, 5.31, 42.81, 4.17, 41.86, 2.77, 40.93, 1.51, 40.29, 0.67, 39.88,
	0.14, 39.64, 0.01, 39.44, 0.01, 39.19, 0, 38.76, 0, 38.01, 0.18, 37.19, 0.95, 36.43, 2.19, 35.83,
	3.92, 35.36, 6.08, 34.87, 8.33, 34.34, 11.32, 33.78, 14.81, 33.29, 18.56, 33.09, 22.37, 33.09,
	25.69, 33.09, 28.3, 33.09, 30.04, 33.09, 31.27, 33.09, 32.34, 33, 33.5, 32.79, 34.83, 32.71,
	36.47, 32.71, 37.96, 32.71, 38.99, 32.64, 39.58, 32.57, 39.86, 32.57, 40.12, 32.57, 40.33, 32.57,
	40.55, 32.57, 40.93, 32.57, 41.3, 32.57, 41.56, 32.57, 41.61, 32.57, 40.96, 32.57, 39.33, 32.57,
	37.22, 32.57, 34.67, 32.57, 31.33, 32.42, 27.68, 31.98, 23.8, 31.39, 19.79, 30.84, 16.49, 30.34,
	13.73, 29.84, 11.21, 29.48, 9.4, 29.27, 8.46, 29.07, 8.01, 28.98, 7.73, 28.77, 7.57, 28.45, 7.42,
	28.04, 7.14, 27.35, 6.72, 26.57, 6.24, 25.99, 5.92, 25.53, 5.73, 25.19, 5.63, 24.91, 5.63, 24.62,
	5.63, 24.42, 5.63, 24.21, 5.63, 23.94, 5.63, 23.63, 5.84, 23.13, 6.5, 22.39, 7.56, 21.6, 8.72,
	20.9, 10.04, 20.38, 11.53, 19.96, 13.02, 19.65, 14.53, 19.44, 16.2, 19.37, 18.23, 19.37, 20.43,
	19.37, 22.54, 19.37, 24.48, 19.37, 26.27, 19.37, 28.62, 19.37, 31.15, 19.55, 33.76, 20.03, 36.9,
	20.49, 39.98, 20.77, 42.64, 20.98, 44.99, 20.98, 47.31, 20.98, 49.53, 20.98, 51.78, 20.74, 54.14,
	20.29, 56.15, 19.88, 57.58, 19.61, 58.31, 19.49, 58.69, 19.24, 58.97, 19.03, 59.09, 18.82, 59.17,
	18.52, 59.26, 18.03, 59.26, 17.19, 59.26, 16.23, 59.26, 15.34, 59.21, 14.58, 58.76, 13.86, 57.72,
	13.16, 56.08, 12.59, 54.1, 12.13, 52.21, 11.73, 50.31, 11.49, 48.49, 11.38, 46.86, 11.16, 45.33,
	10.96, 44.09, 10.81, 43.13, 10.44, 42.33, 10.02, 41.65, 9.44, 41.05, 8.86, 40.54, 8.36, 40.13,
	7.97, 39.9, 7.71, 39.84, 7.2, 39.84, 6.39, 39.84, 5.44, 39.98, 4.34, 40.51, 3.3, 41.39, 2.52,
	42.26, 1.96, 43.11, 1.51, 43.99, 1.17, 44.74, 0.82, 45.49, 0.52, 46.36, 0.28, 47.51, 0.13, 48.85,
	0.04, 50.24, 0, 51.58, 0, 52.71, 0, 53.73, 0, 55.01, 0, 56.49, 0, 57.97, 0, 59.22, 0.18, 60.16,
	0.56, 61.22, 0.96, 62.41, 1.63, 63.9, 2.5, 65.55, 3.48, 67.1, 4.45, 68.61, 5.27, 69.91, 6.06,
	71.05, 6.8, 72.07, 7.51, 72.92, 8.43, 73.83, 9.9, 74.92, 11.78, 76.03, 13.8, 77.02, 16.13, 78,
	18.48, 78.78, 21.29, 79.36, 24.85, 79.68, 28.57, 79.71, 32, 79.71, 35.25, 79.71, 38.08, 79.71,
	39.95, 79.71, 41.04, 79.71, 41.63, 79.71, 42.13, 79.71, 42.61, 79.71, 43.11, 79.71, 43.59, 79.64,
	44.06, 79.55, 44.41, 79.49, 44.58, 79.39,
]

for (let i = 0; i < RAW_HAND_POINTS.length; i += 2) {
	HAND_POINTS.push({
		x: RAW_HAND_POINTS[i], // flipped horizontally
		y: RAW_HAND_POINTS[i + 1],
		z: 0.5,
	})
}

const POINTER_POINTS: VecModel[] = []
const RAW_POINTER_POINTS = [
	0.19, 0.87, 0.19, 0.82, 0.19, 0.86, 0.19, 1.23, 0.19, 2.46, 0.19, 4.2, 0.19, 6.21, 0.19, 8.67,
	0.19, 11.13, 0.19, 13.75, 0.19, 16.62, 0.19, 19.74, 0.19, 22.86, 0.19, 27.56, 0.19, 31.41, 0.19,
	33.67, 0.19, 37.13, 0.19, 41.08, 0.19, 46.19, 0.19, 51.36, 0.19, 55.16, 0.19, 58.69, 0.19, 62.68,
	0.19, 66.77, 0.12, 69.21, 0.03, 70.47, 0.01, 72.18, 0, 73.61, 0, 74.52, 0, 75.04, 0, 75.43, 0,
	75.62, 0, 75.74, 0, 75.84, 0, 75.94, 0, 75.94, 0.04, 75.8, 0.15, 75.53, 0.52, 74.91, 1.01, 74.22,
	1.59, 73.47, 2.49, 72.37, 3.63, 70.88, 5.09, 68.91, 6.8, 66.64, 8.55, 64.29, 10.32, 61.93, 11.54,
	60.21, 12.5, 58.8, 13.7, 57.23, 14.75, 55.83, 15.49, 54.75, 16.02, 54.14, 16.39, 53.77, 16.57,
	53.52, 16.68, 53.34, 16.79, 53.24, 16.89, 53.13, 16.94, 53.12, 17, 53.34, 17.3, 53.93, 17.81,
	54.79, 18.38, 55.84, 19.03, 57.22, 19.75, 59, 20.49, 60.84, 21.33, 62.65, 22.09, 64.68, 22.53,
	66.04, 22.94, 67.35, 23.49, 68.95, 24, 70.18, 24.39, 71.25, 24.76, 72.17, 25.03, 73.1, 25.23,
	73.75, 25.42, 74.27, 25.7, 75.14, 25.98, 75.94, 26.24, 76.67, 26.56, 77.62, 26.76, 78.33, 26.91,
	78.88, 27.05, 79.29, 27.16, 79.5, 27.29, 79.7, 27.35, 79.82, 27.36, 79.93, 27.41, 79.99, 27.54,
	80, 27.75, 79.89, 27.98, 79.7, 28.33, 79.5, 28.76, 79.21, 29.31, 78.89, 29.86, 78.58, 30.41,
	78.27, 31.06, 77.94, 31.85, 77.59, 32.5, 77.31, 33.04, 76.97, 33.81, 76.54, 34.58, 76.18, 35.31,
	75.74, 36.05, 75.29, 36.65, 74.94, 37.14, 74.62, 37.53, 74.39, 37.82, 74.23, 38.09, 74.09, 38.29,
	73.97, 38.42, 73.9, 38.54, 73.84, 38.63, 73.79, 38.69, 73.69, 38.69, 73.48, 38.64, 73.25, 38.52,
	73, 38.37, 72.54, 38.14, 71.98, 37.91, 71.44, 37.52, 70.49, 37.12, 69.42, 36.72, 68.34, 36.08,
	66.94, 35.54, 65.69, 34.99, 64.31, 34.18, 62.54, 33.47, 61.1, 32.91, 59.88, 32.36, 58.6, 31.76,
	57.28, 31.11, 56.12, 30.7, 55.31, 30.39, 54.61, 30.04, 53.8, 29.68, 53, 29.41, 52.3, 29.23, 51.71,
	29.07, 51.24, 28.93, 50.87, 28.81, 50.67, 28.69, 50.49, 28.62, 50.31, 28.57, 50.26, 28.52, 50.21,
	28.46, 50.1, 28.36, 49.99, 28.31, 49.91, 28.27, 49.83, 28.18, 49.73, 28.13, 49.63, 28.11, 49.52,
	28.24, 49.45, 28.58, 49.44, 28.92, 49.44, 29.26, 49.44, 29.89, 49.44, 30.52, 49.44, 31.06, 49.44,
	31.72, 49.44, 33.17, 49.44, 33.73, 49.3, 34.41, 49.16, 35.2, 49.13, 35.97, 49.05, 36.65, 48.97,
	37.34, 48.88, 38.02, 48.72, 38.61, 48.63, 39.07, 48.55, 39.51, 48.41, 39.96, 48.33, 40.31, 48.26,
	40.65, 48.2, 40.99, 48.14, 41.24, 48.08, 41.42, 48.08, 41.59, 48.08, 41.74, 48.08, 41.88, 48.08,
	42.04, 48.08, 42.15, 48.08, 42.27, 48.08, 42.39, 48.08, 42.48, 48.08, 42.58, 48.08, 42.75, 48.08,
	42.99, 48.08, 43.17, 48.08, 43.29, 48.08, 43.4, 48.08, 43.5, 48.08, 43.61, 48.08, 43.72, 48.08,
	43.72, 48.04, 43.63, 47.89, 43.45, 47.59, 43.17, 47.23, 42.82, 46.86, 42.37, 46.4, 41.69, 45.63,
	41, 44.76, 40.3, 43.86, 39.44, 42.79, 38.61, 41.75, 37.63, 40.56, 36.28, 38.95, 34.91, 37.34,
	33.55, 35.73, 32.18, 34.13, 31.2, 33.03, 29.79, 31.73, 28.46, 30.44, 27.45, 29.34, 26.21, 28.07,
	25.03, 26.78, 23.7, 25.35, 22.34, 23.76, 21.05, 22.03, 19.99, 20.71, 18.99, 19.55, 17.99, 18.32,
	16.97, 17.19, 15.95, 16.06, 15.09, 14.99, 13.92, 13.72, 12.8, 12.58, 11.83, 11.61, 10.68, 10.35,
	9.54, 9.1, 8.71, 8.27, 8.06, 7.51, 7.24, 6.48, 6.55, 5.6, 5.9, 4.95, 5.45, 4.55, 5.24, 4.28, 5.05,
	4.06, 4.92, 3.92, 4.74, 3.74, 4.51, 3.51, 3.8, 2.85, 3.36, 2.5, 2.93, 2.1, 2.55, 1.73, 2.19, 1.43,
	1.88, 1.14, 1.67, 0.93, 1.48, 0.81, 1.41, 0.69, 1.36, 0.59, 1.26, 0.5, 1.16, 0.4, 1.06, 0.29,
	0.98, 0.24, 0.87, 0.19, 0.76, 0.1, 0.68, 0.05, 0.62, 0,
]

for (let i = 0; i < RAW_POINTER_POINTS.length; i += 2) {
	POINTER_POINTS.push({
		x: RAW_POINTER_POINTS[i], // flipped horizontally
		y: RAW_POINTER_POINTS[i + 1],
		z: 0.5,
	})
}

const DRAW_POINTS: VecModel[] = []
const RAW_DRAW_POINTS = [
	65.85, 4.52, 65.85, 4.52, 65.81, 4.64, 64.43, 6.51, 60.95, 10.99, 55.52, 17.48, 48.5, 25.57,
	39.91, 34.6, 30.69, 43.73, 23.32, 51.31, 16.86, 58.16, 11.59, 63.77, 8.12, 67.48, 5.4, 70.45,
	3.72, 72.23, 2.79, 73.13, 2.37, 73.53, 2.24, 73.72, 2.24, 74, 2.15, 74.87, 1.87, 76.46, 1.49,
	78.61, 1.06, 80.85, 0.65, 82.74, 0.27, 84.14, 0.09, 84.86, 0.07, 85.19, 0.07, 85.36, 0.04, 85.42,
	0, 85.46, 0.05, 85.48, 0.16, 85.41, 0.43, 85.26, 1.37, 84.84, 3.27, 83.87, 6.47, 82, 9.86, 79.88,
	12.52, 78.2, 14.44, 77.03, 15.27, 76.51, 15.6, 76.29, 15.78, 76.24, 15.85, 76.21, 15.85, 76.12,
	16.03, 75.65, 17.02, 74.27, 19.26, 71.74, 22.8, 67.9, 27.26, 62.85, 32.21, 57.23, 37.42, 51.59,
	42.12, 46.48, 45.74, 42.43, 48.79, 39.2, 51.56, 36.27, 54.35, 33.23, 57.7, 29.43, 61, 25.59,
	63.53, 22.78, 65.63, 20.58, 68.03, 18.04, 70.38, 15.66, 72.3, 13.9, 74.17, 12.22, 75.72, 10.9,
	76.66, 10.19, 77.15, 9.88, 77.38, 9.75, 77.45, 9.67, 77.34, 9.55, 76.82, 9.33, 75.94, 8.94, 74.86,
	8.3, 73.72, 7.54, 72.7, 6.78, 71.73, 6.03, 70.89, 5.36, 70.18, 4.89, 69.59, 4.43, 69.19, 3.98,
	68.89, 3.59, 68.75, 3.28, 68.72, 3.06, 68.72, 2.93, 68.72, 2.76, 68.72, 2.42, 68.85, 1.83, 69.42,
	1.12, 70.1, 0.54, 70.56, 0.22, 70.88, 0.05, 71.18, 0, 71.66, 0, 72.36, 0, 73.38, 0.02, 74.75,
	0.44, 76.17, 1.23, 77.41, 2.06, 78.48, 2.89, 79.16, 3.49, 79.53, 3.91, 79.83, 4.2, 79.96, 4.34,
	79.98, 4.46, 80, 4.57, 80, 4.68, 79.99, 4.81, 79.88, 4.97, 79.69, 5.08, 79.53, 5.24, 79.18, 5.49,
	78.59, 5.74, 77.94, 6.01, 77.44, 6.26, 77.17, 6.42, 77.04, 6.53,
]

for (let i = 0; i < RAW_DRAW_POINTS.length; i += 2) {
	DRAW_POINTS.push({
		x: RAW_DRAW_POINTS[i], // flipped horizontally
		y: RAW_DRAW_POINTS[i + 1],
		z: 0.5,
	})
}

const minX = Math.min(...DRAW_POINTS.map((p) => p.x))
const minY = Math.min(...DRAW_POINTS.map((p) => p.y))

for (const point of DRAW_POINTS) {
	point.x = point.x - minX
	point.y = point.y - minY
}

const maxX = Math.max(...DRAW_POINTS.map((p) => p.x))
const maxY = Math.max(...DRAW_POINTS.map((p) => p.y))

let desiredW = 70
let desiredH = 70

if (maxX > maxY) {
	desiredH = (desiredW / maxX) * maxY
} else {
	desiredW = (desiredH / maxY) * maxX
}

for (const point of DRAW_POINTS) {
	point.x = Number(((point.x / maxX) * desiredW).toFixed(2))
	point.y = Number(((point.y / maxY) * desiredH).toFixed(2))
}

function scalePoints(points: VecModel[], scale: number) {
	return points.map((p) => ({
		x: p.x * scale,
		y: p.y * scale,
		z: p.z,
	}))
}

const SCALES = {
	s: 0.5,
	m: 1,
	l: 1.5,
	xl: 2,
}
